package top.yqingyu.trans$client.api;

import top.yqingyu.common.qydata.DataMap;
import top.yqingyu.qymsg.*;
import top.yqingyu.trans$client.exception.LoginFailureException;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class GetSocket implements Callable<Socket> {

    private ConnectionConfig config;
    private DataMap loginData;

    GetSocket(ConnectionConfig config, DataMap loginData) {
        this.config = config;
        this.loginData = loginData;
    }

    public GetSocket() {
    }

    public static Socket get(ConnectionConfig config) throws Exception {
        return get(config, config.loginData);
    }

    public static Socket get(ConnectionConfig config, DataMap data) throws Exception {
        GetSocket th = new GetSocket(config, data);
        FutureTask<Socket> futureTask = new FutureTask<>(th);
        Thread thread = new Thread(futureTask);
        thread.setDaemon(true);
        thread.start();
        try {
            return futureTask.get(config.LOGIN_TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            throw new LoginFailureException("登陆失败", e);
        }
    }

    @Override
    public Socket call() throws Exception {
        Socket socket = new Socket();
//        socket.setSoTimeout(15000);
        socket.setKeepAlive(true);
        socket.connect(new InetSocketAddress(config.HOST, config.PORT));

        QyMsg AcMsg = new QyMsg(MsgType.AC, DataType.JSON);

        AcMsg.setFrom(config.CLIENT_USER_ID);
        AcMsg
                .putMsgData("AC_STR", config.AC_STR)
                .putMsgData("LAN_Address", socket.getLocalAddress().getHostAddress())
                .putMsgData("LOGIN_DATA", loginData);
        config.msgTransfer.writeQyMsg(socket, AcMsg);
        QyMsg qyMsg = config.msgTransfer.readQyMsg(socket, new AtomicBoolean(true));
        if (qyMsg.getMsgType().equals(MsgType.AC)) {
            if (!loginData.getString("AC_STR", config.AC_STR).equals(MsgHelper.gainMsg(qyMsg))) {
                throw new LoginFailureException("check your ac str");
            }
        } else {
            throw new LoginFailureException("not a stander connect msg " + qyMsg);
        }
        return socket;

    }
}
